import { debounce, last } from 'lodash-es';
import { toJS } from 'mobx';
import { deepObserve } from 'mobx-utils';

class History {

  // TODO: 控制大小，来控制内存的消耗
  undos = [];
  redos = [];
  stopWatch = null;
  // 发生数据变化后，最多再等500ms，把距离上次的数据变更存储起来。
  // 所以waitTime值越小，History对数据变化越敏感，存的undos就越细。
  waitTime = 500;

  add(data) {
    this.undos.push(data);
    this.redos = [];
  }

  undoAble() {
    // undos栈顶就是当前图渲染出来的数据。
    return this.undos.length > 1;
  }

  undo() {
    if (!this.undoAble()) return;

    const curData = this.undos.pop();
    this.redos.push(curData);
    return this.undos.pop();
  }

  redoAble() {
    return this.redos.length > 0;
  }

  redo() {
    if(!this.redoAble()) return;
    return this.redos.pop();
  }

  watch(model) {
    this.stopWatch && this.stopWatch();

    // 把当前watch的model转换一下数据存起来，无需清空redos。
    this.undos.push( toJS(model) );

    this.stopWatch = deepObserve(model, debounce(() => {
      // 数据变更后，把最新的当前model数据存起来，并清空redos。
      // 因为这个回调函数的触发，一般是用户交互而引起的，所以按正常逻辑需要清空redos。
      this.add( toJS(model) );
    }, this.waitTime));
  }
}

export default History;
